gui/macOS: Avoid url domain extensions matching bundle type extensions breaking acces...
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Mon, 10 Feb 2025 05:50:27 +0000 (13:50 +0800)
committerMatthieu Gallien <matthieu.gallien@nextcloud.com>
Mon, 10 Feb 2025 11:01:06 +0000 (12:01 +0100)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
src/gui/macOS/fileproviderdomainmanager_mac.mm

index 022b2685ed1cfd4a87bb5e008962e30de8fe3d8e..b75c59bf7abeee93cb9ddc611bb0da1b693a9216 100644 (file)
  */
 
 #include "configfile.h"
+
 #import <FileProvider/FileProvider.h>
 
+#include <QLatin1StringView>
 #include <QLoggingCategory>
 #include <QRegularExpression>
 
 // are consistent throughout these classes
 namespace {
 
+static constexpr auto bundleExtensions = std::array{
+    QLatin1StringView(".app"),
+    QLatin1StringView(".framework"),
+    QLatin1StringView(".kext"),
+    QLatin1StringView(".plugin"),
+    QLatin1StringView(".docset"),
+    QLatin1StringView(".xpc"),
+    QLatin1StringView(".qlgenerator"),
+    QLatin1StringView(".component"),
+    QLatin1StringView(".saver"),
+    QLatin1StringView(".mdimporter")
+};
+
 QString domainIdentifierForAccount(const OCC::Account * const account)
 {
     Q_ASSERT(account);
+    auto domainId = account->userIdAtHostWithPort();
+    Q_ASSERT(!domainId.isEmpty());
+
     static const QRegularExpression illegalChars("[:/]");
-    return account->userIdAtHostWithPort().replace(illegalChars, "-");
+    domainId.replace(illegalChars, "-");
+
+    // Some url domains like .app cause issues on macOS as these are also bundle extensions.
+    // Under the hood, fileproviderd will create a folder for the user to access the files named
+    // after the domain identifier. If the url domain is the same as a bundle extension, Finder
+    // will interpret this folder as a bundle and will not allow the user to access the files.
+    // Here we wrap the dot in the url domain extension to prevent this from happening.
+    for (const auto &ext : bundleExtensions) {
+        if (domainId.endsWith(ext)) {
+            domainId = domainId.left(domainId.length() - ext.length());
+            domainId += "(.)" + ext.right(ext.length() - 1);
+            break;
+        }
+    }
+
+    return domainId;
 }
 
 QString domainIdentifierForAccount(const OCC::AccountPtr account)